package org.example.com.Utils;

import javassist.NotFoundException;
import org.example.Annoation.Controller;
import org.example.Annoation.RequestMapping;
import org.example.com.model.URLMapping;
import org.reflections.Reflections;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author cc
 * @date 2021/8/2 20:03
 * @Description 工厂设计模式，把所有通过注解的地址请求的 放入map ，按需所取
 */

public class ScanAllClassUtils {
    private static HashMap<String, URLMapping> map =new HashMap<>();
    //整个程序加载的时候加载方法区，并没有进行初始化
    static {
        try {
            map = getUrlMappings("org.example");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        }
    }
    public static URLMapping getUrlMapping(String uri) throws InstantiationException, IllegalAccessException {
        return map.get(uri);
    }
    private static  HashMap<String, URLMapping> getUrlMappings(String BasePackage) throws IllegalAccessException, InstantiationException, NotFoundException {
        Reflections reflections = new Reflections(BasePackage);

        //typesAnnotatedWith获取所有标注了@Controller 的类
        Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(Controller.class);
        for (Class<?> aClass : typesAnnotatedWith) {
            StringBuffer BaseUrl = new StringBuffer("");
            //获取目标类的所有方法
            Method[] declaredMethods = aClass.getDeclaredMethods();
            //获取类方法上的注解
            RequestMapping ClassAnnoation = aClass.getAnnotation(RequestMapping.class);
            if (ClassAnnoation!=null){
                BaseUrl.append(ClassAnnoation.value());
            }
            //获取类的实例
            Object o = aClass.newInstance();

            // 获取类中所有的方法
            for (Method declaredMethod : declaredMethods) {
                //获取类 方法上的注解
                RequestMapping annotation = declaredMethod.getAnnotation(RequestMapping.class);
                if (annotation!=null){
                    StringBuffer buffer = new StringBuffer(BaseUrl);
                    buffer.append(annotation.value());
                    //调用方法 获取参数名字和值
                    Map<String, Class<?>> partamsAndName = GetParasmnameAndTypeUtils.getPartamsName(aClass, declaredMethod);

                    //添加参数的姓名,类型,
                    //class org.example.com.Controller.UserController ; Userlist : sys/user/find
//                    System.out.println(aClass +"; 方法是"+declaredMethod.getName() +": 位置在"+buffer.toString());
                    map.put(buffer.toString(),new URLMapping(o,declaredMethod,partamsAndName));
                }
            }
        }
        return map;


    }



//    public static void main(String[] args) {
//        try {
////            HashMap<String, URLMapping> urlMapping = ScanAllClassUtils.getUrlMappings("org.example");
//            URLMapping urlMapping = getUrlMapping("/sys/user/find");
//            Object invoke = urlMapping.getMethod().invoke(urlMapping.getObj());
//
////            System.out.println(urlMapping.getMethod().getName()+" "+urlMapping.getObj()+" "+invoke.toString());
////            System.out.println(invoke);
//
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        } catch (InstantiationException | InvocationTargetException e) {
//            e.printStackTrace();
//        }
//    }
}
